#include "MsgRounter.h"
#include "Game.h"

MsgRounter::MsgRounter()
{
	//ctor
		m_isServerInit = false;
		m_isClientInit = false;
}

MsgRounter::~MsgRounter()
{
	//dtor
}

void MsgRounter::ServerRounter(Message* _pMsg)
{
	if(!m_isServerInit)
	{
		ServerInit();
	}

	eCmd curCmd = _pMsg->m_cmd;
	if(this->m_ServerMsgCallMap.count(curCmd)== 0)
	{
		Debug::Log("ServerRounter error, not found in map: ", (int)curCmd);
		return;
	}

	this->m_ServerMsgCallMap[curCmd](_pMsg);
}

void MsgRounter::ServerInit()
{
	ServerAllRegister();
	m_isServerInit = true;
}

void MsgRounter::ClientRounter(Message* _pMsg)
{
	if(!m_isClientInit)
	{
		ClientInit();
	}

	eCmd curCmd = _pMsg->m_cmd;
	if(this->m_ClientMsgCallMap.count(curCmd)== 0)
	{
		Debug::Log("ServerRounter error, not found in map: ", (int)curCmd);
		return;
	}

	this->m_ClientMsgCallMap[curCmd](_pMsg);
}

void MsgRounter::ClientInit()
{
	ClientAllRegister();
	m_isClientInit = true;
}



void OnSYSCheckAnswer(Message* _pMsg)
{
	int retKey = _pMsg->GetInt();
	bool isServer = _pMsg->GetBool();

	//Debug::Log("Recv SYS_Check_Answer");

	// 返回key不对， 不是我们程序 关闭链接
	if(retKey != 8259 || !isServer)
	{
		Debug::Warn("Not our process, shutdown connect.");
		Game::GetInstance().GetSock()->ShutDownAConnect(_pMsg->m_fd);
		return;
	}

	// 链接的socket客户端通过验证
	Client* pClient = Game::GetInstance().GetSock()->GetClient(_pMsg->m_fd);
	if(pClient == nullptr)
	{
		return;
	}
	pClient->m_isPassCheck = true;

	// 请求服务器信息
	Message Msg(_pMsg->m_fd, eCmd::W2G_Login_Info);
	Message::Send(&Game::GetInstance().GetSock()->GetMsgQunue(), &Msg);
}

void OnG2WLoginInfo(Message* _pMsg)
{
	//Debug::Log("eCmd::G2W_Login_Info");
	GameServerInfo Info;
	Info.m_id = _pMsg->GetInt();
	Info.m_name = _pMsg->GetString();
	Info.m_count = _pMsg->GetInt();
	Info.m_ip = _pMsg->GetString();
	Info.m_port = _pMsg->GetInt();

	Game::GetInstance().GetLogin()->m_WorldServerInfo.AddGameServerInfo(Info);
	bool isUpdate = Game::GetInstance().GetLogin()->UpdateLoginServer();
	if(isUpdate)
	{
		Game::GetInstance().GetLogin()->W2LUpdateLoginServerInfo();
	}

}


void OnSYSCheckAsk(Message* _pMsg)
{
	//Debug::Log("case eCmd::SYS_Check_Ask:");
	int key = _pMsg->GetInt();
	if(key != 9527)
	{
		Debug::Error("key Error ???");
		return;
	}

	int retKey = 8259;
	bool isServer = true;

	Message Msg(Game::GetInstance().GetSockClient()->GetFd(), eCmd::SYS_Check_Answer);
	Msg.AddInt(retKey);
	Msg.AddBool(isServer);
	Message::Send(&Game::GetInstance().GetSockClient()->GetMsgQunue(), &Msg);
}

void OnL2WLoginInfo(Message* _pMsg)
{
	//Debug::Log("eCmd::L2W_Login_Info");
	Login* pLoginData = Game::GetInstance().GetLogin();
	int id = pLoginData->m_WorldServerInfo.m_id;
	string serverName = pLoginData->m_WorldServerInfo.m_name;
	int state = (int)pLoginData->m_WorldServerInfo.m_State;
	string loginIp = "";
	int loginPort = 0;

	Message Msg(Game::GetInstance().GetSockClient()->GetFd(), eCmd::W2L_Login_Info);
	Msg.AddInt(id);
	Msg.AddString(serverName);
	Msg.AddInt(state);
	Msg.AddString(loginIp);
	Msg.AddInt(loginPort);
	Message::Send(&Game::GetInstance().GetSockClient()->GetMsgQunue(), &Msg);
}

void AddRoleDataToMsg(Role* _pRole, Message* _pMsg)
{
	Debug::Log(__func__);
	if(_pRole == nullptr)
	{
		Debug::Error(__func__, " pRole == null");
		return;
	}

	_pMsg->AddInt(_pRole->m_oid);
	_pMsg->AddInt(_pRole->m_cfgId);
	_pMsg->AddInt(_pRole->m_type);
	_pMsg->AddInt(_pRole->m_lv);
	_pMsg->AddInt(_pRole->m_exp);

	_pMsg->AddInt(_pRole->m_hp);
	_pMsg->AddInt(_pRole->m_countryId);
	_pMsg->AddInt(_pRole->m_cityId);
	_pMsg->AddInt(_pRole->m_buildId);
	_pMsg->AddInt(_pRole->m_jobId);

	_pMsg->AddInt(_pRole->m_houseId);
	_pMsg->AddString(_pRole->m_name);
	_pMsg->AddString(_pRole->m_desc);
}

void AddPlayerDataToMsg(Player* _pPlayer, Message* _pMsg)
{
	if(_pPlayer == nullptr)
	{
		Debug::Error(__func__, " _pPlayer == null");
		return;
	}

	_pMsg->AddInt(_pPlayer->m_oid);
	_pMsg->AddInt(_pPlayer->m_uid);
	_pMsg->AddInt(_pPlayer->m_silver);
	_pMsg->AddInt(_pPlayer->m_diamond);

	int roleId = _pPlayer->m_roleId;
	Role* pRole = Game::GetInstance().GetRoleMgr()->Get(roleId);

	AddRoleDataToMsg(pRole, _pMsg);
}



void OnG2WLoginRoleInfo(Message* _pMsg)
{
	int userId = _pMsg->GetInt();

	PlayerManager* pPlayerMgr = Game::GetInstance().GetPlayerMgr();
	int playerId = pPlayerMgr->GetPlayerId(userId);

	// PlayerId == -1 代表未创建玩家
	Message Msg(_pMsg->m_fd, eCmd::W2G_Login_Role_Info);
	Msg.AddInt(userId);
	Msg.AddInt(playerId);
	if(playerId > 0)
	{
		// 插入玩家数据
		Player* Player1 = pPlayerMgr->GetPlayer(playerId);
		AddPlayerDataToMsg(Player1, &Msg);
	}

	Message::Send(&Game::GetInstance().GetSock()->GetMsgQunue(), &Msg);
}



void OnG2WPlayerCreate(Message* _pMsg)
{
	int userId = _pMsg->GetInt();
	int roleCfgId = _pMsg->GetInt();
	string playerName = _pMsg->GetString();

	int retCode = 0;
	PlayerManager* pPlayerMgr = Game::GetInstance().GetPlayerMgr();
	RoleManager* pRoleMgr = Game::GetInstance().GetRoleMgr();
	GlobalManager* pGlobalMgr = Game::GetInstance().GetGobalMgr();
	int playerId = pPlayerMgr->Create(userId, roleCfgId, playerName, pRoleMgr, pGlobalMgr);
	if(playerId < 0)
		retCode = playerId;

	Message Msg(_pMsg->m_fd, eCmd::W2G_Player_Create);
	Msg.AddInt(userId);
	Msg.AddInt(retCode);
	Msg.AddInt(playerId);
	if(playerId > 0)
	{
		// 插入玩家数据
		Player* pPlayer = pPlayerMgr->GetPlayer(playerId);
		AddPlayerDataToMsg(pPlayer, &Msg);
	}


	Message::Send(&Game::GetInstance().GetSock()->GetMsgQunue(), &Msg);
}

void MsgRounter::ServerAllRegister()
{
	m_ServerMsgCallMap.insert(pair<eCmd, pFunc>(eCmd::SYS_Check_Answer, 			OnSYSCheckAnswer));
	m_ServerMsgCallMap.insert(pair<eCmd, pFunc>(eCmd::G2W_Login_Info, 				OnG2WLoginInfo));
	m_ServerMsgCallMap.insert(pair<eCmd, pFunc>(eCmd::G2W_Login_Role_Info,			OnG2WLoginRoleInfo));
	m_ServerMsgCallMap.insert(pair<eCmd, pFunc>(eCmd::G2W_Player_Create,			OnG2WPlayerCreate));

}

void MsgRounter::ClientAllRegister()
{
	m_ClientMsgCallMap.insert(pair<eCmd, pFunc>(eCmd::SYS_Check_Ask, 				OnSYSCheckAsk));
	m_ClientMsgCallMap.insert(pair<eCmd, pFunc>(eCmd::L2W_Login_Info, 				OnL2WLoginInfo));
}








//// 发送消息路由入口
//void MsgRounter::SendRounter(Message* _pMsg)
//{
//	_pMsg->Encode();
//
//	if(!MsgCheck(_pMsg)){
//		return;
//	}
//
//
//	// YU_TODO: 应该是不同的 write at here。 各种if吧
//	// m_ServerSock.GetMsgQunue().PushSendMsg(_pMsg);
//}
//
//
//// 消息路由
//bool MsgRounter::MsgCheck(Message* _pMsg)
//{
//	int cmd = (int)_pMsg->m_cmd;
//	if(( cmd < MSG_CMD_MIN) && (cmd > MSG_CMD_MAX))
//	{
//		cout<< "Error. cmd beyond limit."<< endl;
//		cout<< "Error at Msg.Send(), sorry, I don't know which shall I send to."<< endl;
//		return false;
//	}
//
//	return true;
//}
